// Package secrets 定义了加密和解密配置数据的接口
// 加密器负责将配置数据加密为字节流，或将字节流解密为配置数据
// 不同的加密器可以支持不同的加密算法，如 AES、RSA 等
// 加密器的实现可以是对称加密算法，也可以是非对称加密算法
// 对称加密算法使用相同的密钥进行加密和解密
// 非对称加密算法使用公钥加密，私钥解密
// 加密器的实现可以是基于 Go 标准库的，也可以是基于第三方库的
// 基于 Go 标准库的加密器实现可以是 crypto/aes、crypto/rsa 等
// 基于第三方库的加密器实现可以是 github.com/sethvargo/go-password 等

package secrets

import "context"

// Encryptor 加密器接口
type Encryptor interface {
	// Init 初始化加密器
	Init(...Option) error
	// Options 返回加密器的选项
	Options() Options
	// Decrypt 解密数据
	Decrypt([]byte, ...DecryptOption) ([]byte, error)
	// Encrypt 加密数据
	Encrypt([]byte, ...EncryptOption) ([]byte, error)
	// String 返回加密器的名称
	String() string
}

type Options struct {
	// Key 对称加密算法的密钥
	Key []byte
	// PrivateKey 非对称加密算法的私钥
	PrivateKey []byte
	// PublicKey 非对称加密算法的公钥
	PublicKey []byte
	// Context 加密器的上下文
	Context context.Context
}

// Option 加密器的选项
type Option func(*Options)

// Key 设置对称加密算法的密钥

func Key(k []byte) Option {
	return func(o *Options) {
		o.Key = make([]byte, len(k))
		copy(o.Key, k)
	}
}

// PublicKey 设置非对称加密算法的公钥
func PublicKey(key []byte) Option {
	return func(o *Options) {
		o.PublicKey = make([]byte, len(key))
		copy(o.PublicKey, key)
	}
}

// PrivateKey 设置非对称加密算法的私钥
func PrivateKey(key []byte) Option {
	return func(o *Options) {
		o.PrivateKey = make([]byte, len(key))
		copy(o.PrivateKey, key)
	}
}

// DecryptOptions 解密选项
type DecryptOptions struct {
	SenderPublicKey []byte
}

// DecryptOption 解密选项

type DecryptOption func(*DecryptOptions)

// SenderPublicKey 设置发送方的公钥
// 发送方的公钥用于验证发送方的身份
// 发送方的公钥可以从发送方的配置文件中获取
func SenderPublicKey(key []byte) DecryptOption {
	return func(d *DecryptOptions) {
		d.SenderPublicKey = make([]byte, len(key))
		copy(d.SenderPublicKey, key)
	}
}

// EncryptOptions 加密选项
type EncryptOptions struct {
	RecipientPublicKey []byte
}

// EncryptOption 加密选项
type EncryptOption func(*EncryptOptions)

// RecipientPublicKey 设置接收方的公钥
// 接收方的公钥用于加密数据
// 接收方的公钥可以从接收方的配置文件中获取
func RecipientPublicKey(key []byte) EncryptOption {
	return func(e *EncryptOptions) {
		e.RecipientPublicKey = make([]byte, len(key))
		copy(e.RecipientPublicKey, key)
	}
}
